package com.dabai.iot.mqtt.util;

import com.dabai.common.core.utils.Func;
import com.dabai.iot.common.enums.ConnectStatus;
import com.dabai.iot.common.model.DeviceInfo;
import com.dabai.iot.mqtt.model.DeviceConnectionSession;
import io.vertx.mqtt.MqttEndpoint;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Mqtt 会话管理
 *
 * @author kev1n
 */
@Slf4j
public class MqttSessionManager {

    // 缓存连接会话
    private final Map<String, DeviceConnectionSession> sessionMap = new ConcurrentHashMap<>(16);

    private MqttSessionManager() {
    }

    public static MqttSessionManager getInstance() {
        return SingletonInstance.instance;
    }

    /**
     * 添加会话
     *
     * @param clientId
     * @param session
     */
    public synchronized ConnectStatus addSession(String clientId, DeviceConnectionSession session) {
        // 检测是否存在连接会话，存在则代表此设备是同 clientId 设备重复连接，需关闭旧连接，保留新连接
        DeviceConnectionSession oldSession = this.getSession(clientId);
        if (Func.isNotEmpty(oldSession)) {
            sessionMap.put(clientId, session);
            oldSession.getMqttEndpoint().close();
            return ConnectStatus.online;
        } else {
            sessionMap.put(clientId, session);
            return ConnectStatus.online;
        }
    }

    /**
     * 获取会话
     *
     * @param clientId
     */
    public DeviceConnectionSession getSession(String clientId) {
        if (sessionMap.containsKey(clientId)) {
            return sessionMap.get(clientId);
        }

        return null;
    }

    /**
     * 移除会话
     *
     * @param clientId
     */
    public void removeSession(String clientId) {
        sessionMap.remove(clientId);
    }

    /**
     * 移除会话
     *
     * @param clientId
     * @param endpoint
     */
    public boolean removeSession(String clientId, MqttEndpoint endpoint) {
        if (getSession(clientId) != null) {
            if (getSession(clientId).getMqttEndpoint().equals(endpoint)) {
                sessionMap.remove(clientId);
                return true;
            }
        }

        return false;
    }

    /**
     * 获取设备连接信息
     *
     * @param clientId
     */
    public DeviceInfo getDeviceInfo(String clientId) {
        DeviceConnectionSession session = getSession(clientId);
        if (session != null) {
            return session.getDeviceInfo();
        }

        return null;
    }

    /**
     * 获取会话数量
     */
    public int getSessionCount() {
        return sessionMap.size();
    }

    private static class SingletonInstance {
        private static final MqttSessionManager instance = new MqttSessionManager();
    }

}
